package com.xunmall.gateway.controller;

import com.xunmall.account.dto.UserDto;
import com.xunmall.account.service.OauthRemoteService;
import com.xunmall.account.service.UserRemoteService;
import com.xunmall.base.constants.SecurityConstants;
import com.xunmall.base.exception.BadRequestException;
import com.xunmall.base.util.StringUtils;
import com.xunmall.gateway.security.SecurityMetadataSourceService;
import com.xunmall.security.GlobalSessionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

/**
 * @author wangyanjing
 */
@RestController
@RequestMapping("/oauth")
public class OauthController implements OauthRemoteService {
    @Autowired
    private SecurityMetadataSourceService metadataSourceService;
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private UserRemoteService userRemoteService;

    @RequestMapping("/userinfo")
    public Principal me(Principal user) {
        return user;
    }

    @RequestMapping("/refresh_meta_source")
    public boolean refreshMetaSource() {
        metadataSourceService.refreshMetaSource();
        return true;
    }

    @Override
    @RequestMapping(value = "/revoke_token", method = RequestMethod.GET)
    public void revokeToken(@RequestParam("userId") String userId) {
        Set<String> roles = GlobalSessionUtil.getRoles();
        if (roles == null || roles.isEmpty()) {
            throw new BadRequestException("error.gateway.0022", this);
        }
        if (StringUtils.isNotBlank(userId)) {
            UserDto user = userRemoteService.getByUuid(userId).getData();
            if (user == null) {
                return;
            }
            Collection<OAuth2AccessToken> accessTokens = new ArrayList<>();
            Collection<OAuth2AccessToken> andAccessTokens = tokenStore.findTokensByClientIdAndUserName(SecurityConstants.CLIENT_ID_ANDROID, user.getMobile());
            if (andAccessTokens != null) {
                accessTokens.addAll(andAccessTokens);
            }
            Collection<OAuth2AccessToken> iosAccessTokens = tokenStore.findTokensByClientIdAndUserName(SecurityConstants.CLIENT_ID_IOS, user.getMobile());
            if (iosAccessTokens != null) {
                accessTokens.addAll(iosAccessTokens);
            }
            Collection<OAuth2AccessToken> webAccessTokens = tokenStore.findTokensByClientIdAndUserName(SecurityConstants.CLIENT_ID_WEB, user.getMobile());
            if (webAccessTokens != null) {
                accessTokens.addAll(webAccessTokens);
            }
            accessTokens.stream().forEach(accessToken -> {
                if (accessToken.getRefreshToken() != null) {
                    tokenStore.removeRefreshToken(accessToken.getRefreshToken());
                }
                tokenStore.removeAccessToken(accessToken);
                GlobalSessionUtil.removeProfile(accessToken.getValue());
            });

        }
    }
}